package com.jifujun.fastdfs_springboot.service.impl;

import com.jifujun.fastdfs_springboot.client.FastDFSClient;
import com.jifujun.fastdfs_springboot.dao.FastDFSDao;
import com.jifujun.fastdfs_springboot.model.FastDFS;
import com.jifujun.fastdfs_springboot.service.FastDFSService;
import com.jifujun.fastdfs_springboot.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Objects;

/**
 * Create with IntelliJ IDEA
 * Project Name: fast_dfs
 * Package Name: com.jifujun.fast_dfs.service
 * Date: 2018/3/2713:38
 * User: 快乐的小菌菌
 * Description:
 */
@Service
@Slf4j
public class FastDFSServiceImpl implements FastDFSService, ApplicationContextAware {
    private FastDFSDao fastDFSDao;
    private FastDFSClient fastDFSClient;
    private ApplicationContext applicationContext;

    public FastDFSServiceImpl(FastDFSDao fastDFSDao) {
        this.fastDFSDao = fastDFSDao;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String upload(String path) {
        fastDFSClient = getBean();
        File file = new File(path);
        String extName = StringUtil.deleteDot(file.getName());
        String[] s = fastDFSClient.uploadFile(path, extName);
        if (Objects.nonNull(s)) {
            fastDFSDao.save(instanceFastDFS(s, extName, (int) file.length(), file.getName()));
            log.info("上传的文件路径为：" + StringUtil.stitchUploadPath(s));
        }
        return StringUtil.stitchUploadPath(s);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String upload(byte[] bytes, String extName, String fileName) {
        fastDFSClient = getBean();
        String[] s = fastDFSClient.uploadFile(bytes, extName);
        if (Objects.nonNull(s)) {
            fastDFSDao.save(instanceFastDFS(s, extName, bytes.length, fileName));
            log.info("上传的文件路径为：" + StringUtil.stitchUploadPath(s));
        }
        return StringUtil.stitchUploadPath(s);
    }

    @Override
    public List<FastDFS> queryList(Integer pageNo, Integer pageSize) {
        return fastDFSDao.queryList();
    }

    @Override
    public FastDFS getById(Integer id) {
        return fastDFSDao.getById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteById(Integer id) {
        String resultCode;
        Integer code;
        fastDFSClient = getBean();
        FastDFS fastDFS = fastDFSDao.getById(id);
        code = fastDFSClient.deleteFile(fastDFS.getGroup_name(), fastDFS.getStorage_path());
        if (code.equals(0)) {
            resultCode = "Delete Success!";
            fastDFSDao.deleteById(id);
        } else {
            resultCode = "Delete Failed! errorCode: " + code;
        }
        log.info("删除状态：" + resultCode);
    }

    @Override
    public void download(Integer id, String localPath) {
        FastDFS fastDFS = fastDFSDao.getById(id);
        byte[] bytes = fastDFSClient.download(fastDFS.getGroup_name(), fastDFS.getStorage_path());
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(localPath);
            fileOutputStream.write(bytes);
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Transactional
    @Override
    public String uploadRemoteLink(String remoteLink) {
        try {
            URL url = new URL(remoteLink);
            URLConnection urlConnection = url.openConnection();
            InputStream inputStream = urlConnection.getInputStream();
            byte[] bytes = new byte[inputStream.available()];
            inputStream.read(bytes);
            return upload(bytes, StringUtil.deleteDot(url.getFile()), StringUtil.deleteSlash(url.getFile()));
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("远程链接上传失败");
        }
    }

    @Override
    public Integer deleteByPath(String path) {
        String resultCode;
        Integer code;
        fastDFSClient = getBean();
        String groupName = path.substring(0, 6);
        //中间去除"/"
        String storagePath = path.substring(7);
        FastDFS fastDFS = fastDFSDao.getByPath(groupName, storagePath);
        code = fastDFSClient.deleteFile(fastDFS.getGroup_name(), fastDFS.getStorage_path());
        if (code.equals(0)) {
            resultCode = "Delete Success!";
            fastDFSDao.deleteByPath(groupName, storagePath);
        } else {
            resultCode = "Delete Failed! errorCode: " + code;
        }
        log.info("删除状态：" + resultCode);
        return code;
    }

    private FastDFS instanceFastDFS(String[] args, String extName, Integer size, String fileName) {
        FastDFS fastDFS = new FastDFS();
        fastDFS.setGroup_name(args[0]);
        fastDFS.setStorage_path(args[1]);
        fastDFS.setExt_name(extName);
        fastDFS.setSize(size);
        fastDFS.setFile_name(fileName);
        return fastDFS;
    }

    public FastDFSClient getBean() {
        return applicationContext.getBean("fastDFSClientImpl", FastDFSClientImpl.class);
    }

}
